package xj.graph2d.app.prop;

import static xj.graph2d.app.resources.Resources.getResourceString;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.geom.Rectangle2D;

import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import xj.graph2d.Command;
import xj.graph2d.DrawAttr;
import xj.graph2d.DrawCanvas;
import xj.graph2d.DrawShape;
import xj.graph2d.FontAttr;
import xj.graph2d.SimpleDrawDocument;
import xj.graph2d.SimpleDrawView;
import xj.graph2d.TextShape;
import xj.graph2d.app.DrawApp;
import xj.graph2d.command.SetAttrCommand;
import xj.graph2d.dialog.DialogPanel;
import xj.graph2d.dialog.TitledDialogPanel;

public class FontListener 
  extends AttrListener 
  implements ActionListener {

  class FontSelectionPanel extends DialogPanel {

    public FontSelectionPanel(String name, String title) { 
      super(name, title, true);
      setPreferredSize(new Dimension(370, 250));

      if (main.isUseStandardFontsOnly()) {
	fontList = new String[] { 
	  "Dialog", 
	  "DialogInput", 
	  "Lucida Bright",
	  "Lucida Sans", 
	  "Lucida Sans Typewriter", 
	  "Monospaced", 
	  "SansSerif",
	  "Serif"
	};
      } else {
	fontList = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
      }
      styleList = new String[] {
	getResourceString("Plain.text"),
	getResourceString("Bold.text"),
	getResourceString("Italic.text"),
	getResourceString("BoldItalic.text")
      };
      styleValues = new int[] { 
	Font.PLAIN, 
	Font.BOLD, 
	Font.ITALIC,
	Font.BOLD | Font.ITALIC
      };
      sizeList = new String[] { 
	"6", "8", "10", "12", "14", "16", "18", "20", 
	"24", "28", "32", "36", "40", "48", "56", "64", 
      };

      int i;
      for (i = 0; i < fontList.length; i++) { 
	fontMenu.addItem(fontList[i]);
      }
      fontMenu.setSelectedItem("Dialog");

      for (i = 0; i < styleList.length; i++) { 
	styleMenu.addItem(styleList[i]);
      }
      styleMenu.setSelectedIndex(0);

      for (i = 0; i < sizeList.length; i++) { 
	sizeMenu.addItem(sizeList[i]);
      }
      sizeMenu.setSelectedItem("12");
      sizeMenu.setEditable(true);

      sample.setFontName("SansSerif");
      sample.setFontStyle(Font.PLAIN);
      sample.setFontSize(12);

      addRow(new JLabel(getResourceString("FontFamily.text")), fontMenu);
      addRow(new JLabel(getResourceString("FontStyle.text")),  styleMenu);
      addRow(new JLabel(getResourceString("FontSize.text")),   sizeMenu);

      sampleLabel.setBorder(BorderFactory.createLoweredBevelBorder());
      JPanel samplePanel = new JPanel();
      samplePanel.setLayout(new BorderLayout());
      //Border border = BorderFactory.createEtchedBorder();
      /*
	TitledBorder border = 
	BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), 
					 " " + getResourceString("FontPreview.text") + " ",
					 TitledBorder.CENTER, TitledBorder.TOP,
					 titleFont, Color.BLACK);
        samplePanel.setBorder(border);
      */
      JLabel titleLabel = new JLabel(getResourceString("FontPreview.text")); 
      titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
      samplePanel.add(titleLabel, BorderLayout.NORTH);

      samplePanel.add(sampleLabel, BorderLayout.CENTER);

      addRow(samplePanel);

      ItemListener l = new ItemListener() {
	public void itemStateChanged(ItemEvent e) {
	  if (e.getStateChange() == ItemEvent.SELECTED) {
	    Object o = e.getSource();
	    if (o == fontMenu) {
	      font = (String) fontMenu.getSelectedItem();
	    } else if (o == styleMenu) {
	      style = Font.PLAIN;
	      int i = styleMenu.getSelectedIndex();
	      if (i >= 0 && i < styleValues.length) {
		style = styleValues[i];
	      }
	    } else if (o == sizeMenu) {
	      size = 12;
	      try {
		size = Integer.parseInt((String) sizeMenu.getSelectedItem());
		if (size < 1 || size > 120) {
		  size = 12;
		}
	      } catch (NumberFormatException se) {
	      }
	    }
	    repaintSample();
	  }
	}
      };
      fontMenu.addItemListener(l);
      styleMenu.addItemListener(l);
      sizeMenu.addItemListener(l);
    }

    String fontList[];

    String styleList[];

    int styleValues[];

    String sizeList[];

    protected void repaintSample() {
      sample.setFontName(font);
      sample.setFontStyle(style);
      sample.setFontSize(size);
      sampleLabel.repaint();
    }

    protected void getValues() {
      size = 12;
      try {
	size = Integer.parseInt((String) sizeMenu.getSelectedItem());
	if (size < 1 || size > 120) {
	  size = 12;
	}
      } catch (NumberFormatException se) {
      }
      font = (String) fontMenu.getSelectedItem();
      style = Font.PLAIN;
      int i = styleMenu.getSelectedIndex();
      if (i >= 0 && i < styleValues.length) {
	style = styleValues[i];
      }
    }

    @Override
    public void setOption() {
      if (updateSystemAttr) {
	SimpleDrawView view = main.getView();
	DrawAttr sysAttr = view.getDrawAttr();
	if (sysAttr != null) {
	  FontAttr fa = sysAttr.getFontAttr();
	  if (fa != null) {
	    font = fa.getFontName();
	    style = fa.getFontStyle();
	    size = fa.getFontSize();
	  }
	}
      }
      resetOptions();
    }

    public void resetOptions() {
      fontMenu.setSelectedItem(font);
      sizeMenu.setSelectedItem(Integer.toString(size));
      int i = 0;
      if (style == Font.PLAIN) {
	i = 0;
      } else if (style == Font.BOLD) {
	i = 1;
      } else if (style == Font.ITALIC) {
	i = 2;
      } else if (style == (Font.BOLD | Font.ITALIC)) {
	i = 3;
      }
      styleMenu.setSelectedIndex(i);
      // repaintSample();
    }

    @Override
    public void applyOption() {
      getValues();

      if (icon != null) { 
	icon.setFontName(font);
	icon.setFontStyle(style);
      }

      if (updateSystemAttr && 
	  attr != null) {
	// update system attribute
	attr.setFont(font, style, size);
      }

      // update current shape
      SimpleDrawDocument doc = main.getDoc();
      SimpleDrawView view = main.getView();
      if (doc != null) {
	DrawShape curShape = doc.getSelectedShape();
	if (curShape instanceof TextShape) {
	  DrawAttr curAttr = curShape.getDrawAttr();
	  if (curAttr != null) {
	    Command cmd = new SetAttrCommand(view, doc, curShape);
	    doc.addCommand(cmd);

	    DrawCanvas canvas = view.getCanvas();
	    DrawShape parent = curShape.getParent();
	    if (parent == null) {
	      doc.remove(curShape);
	    } else {
	      parent.removeShape(curShape);
	    }
	    Rectangle2D r = curShape.getBounds();
	    canvas.repaintRect(r, true, true);
	    curAttr.setFont(font, style, size);
	    if (parent == null) {
	      doc.add(curShape, true);
	    } else {
	      parent.addShape(curShape);
	    }
	    curShape.calculateBounds();
	    canvas.repaintShape(curShape);
	  }
	}
      }
    }

    JComboBox fontMenu = new JComboBox();

    JComboBox styleMenu = new JComboBox();

    JComboBox sizeMenu = new JComboBox();

    FontIcon sample = new FontIcon(250, 80, "ABCxyz");

    JLabel sampleLabel = new JLabel(sample);

  }

  protected TitledDialogPanel fontDialog = null;
  protected FontSelectionPanel fontPanel = null;
  protected boolean showTitlePane = false;
  protected boolean showTitleMessage = true;

  protected DrawAttr attr = null;

  protected FontIcon icon = null;

  protected String font;

  protected int style;

  protected int size;

  public FontListener() {}

  public FontListener(boolean showTitlePane,
		      boolean showTitleMessage) { 
    this.showTitlePane = showTitlePane;
    this.showTitleMessage = showTitleMessage;
  }

  public void init(FontIcon icon) {
    this.icon = icon;
  }

  @Override
  protected void init() {
    Object ic = DrawApp.getIcon("fontIcon");
    if (ic instanceof FontIcon) {
      icon = (FontIcon) ic;
    }
  }

  // used to set the font attr of the current shape 
  public void setAttr(FontAttr fa) {
    if (fa != null) {
      font = fa.getFontName();
      style = fa.getFontStyle();
      size = fa.getFontSize();
    }
  }

  public void actionPerformed(ActionEvent e) {
    if (updateSystemAttr) {
      SimpleDrawView view = main.getView();
      if (view != null) {
	attr = view.getDrawAttr();
      }
    }

    if (fontDialog == null) {
      String fontDialogTitle = getResourceString("FontDialog.title");
      String fontHeader = getResourceString("FontDialog.header");
      String[] fontText = new String[] { 
	getResourceString("FontDialog.text1"),
	getResourceString("FontDialog.text2"),	
      };

      String title = null; 
      if (!showTitlePane && showTitleMessage) { 
	title = fontText[0];
      }
      FontSelectionPanel[] panels = { 
	fontPanel = new FontSelectionPanel(null, title), 
	//getResourceString("Font.title")),
      };
      fontDialog = new TitledDialogPanel(main.getJFrame(), 
					 JOptionPane.OK_CANCEL_OPTION,
					 null, panels);
      fontDialog.setTitle(fontDialogTitle);
      if (showTitlePane) { 
	fontDialog.setTitlePaneText(fontHeader, fontText, null);
      }
    }
    fontDialog.setOptions();
    fontDialog.showOptionDialog();


    AbstractButton comp = null;
    if (source instanceof AbstractButton) {
      comp = (AbstractButton) source;
      comp.repaint();
      comp.setSelected(false);
    }

  }

}
